#include "loadimagebll.h"
#include "log/EZQLOG.h"
#include <QThread>
#include <QApplication>
#include <QEvent>

LoadImageBLL* LoadImageBLL::shareLoadImageBll()
{
    static LoadImageBLL *bll = 0;
    if(bll == 0){
        bll = new LoadImageBLL();
    }
    return bll;
}

LoadImageBLL::LoadImageBLL(QObject *parent) :
    QObject(parent)
{
    this->moveToThread(QThread::currentThread());
    _loadObj = new LoadImageObj(0,this);
//    EZDebug << "LoadImageBLL init";
}
LoadImageBLL::~LoadImageBLL()
{
    delete _loadObj;
}

bool LoadImageBLL::event(QEvent * event)
{
//    EZDebug << event->type();
    bool returnCode = false;
    if(event->type()==QEvent::User+2){
        // this is load image event
        LoadImageFinishEvent *fevent = (LoadImageFinishEvent*)event;
        _callBacksMutex.lock();
        int index = _callBacks.indexOf(fevent->_callBack);
        if(index>=0){
            fevent->_callBack->loadImageFinish(this,fevent);
//            fevent->_callBack->loadImageFinish(this,fevent->_path,fevent->_pixmap,fevent->_error);
        }
        _callBacksMutex.unlock();
        returnCode = true;
    }else{
       returnCode  = QObject::event(event);
    }
    return returnCode;
}

void LoadImageBLL::loadImageFromDisk(const QString &path,LoadImageBllCallBack *callBack)
{

    _callBacksMutex.lock();
    int index = _callBacks.indexOf(callBack);
    if(index < 0){
        _callBacks.append(callBack);
    }
    _callBacksMutex.unlock();

    LoadImageBLLEvent *event = new LoadImageBLLEvent((QEvent::Type)(QEvent::User+1));
    event->setPath(path);
    event->_callBack = callBack;
    QApplication::postEvent(_loadObj,event);
}
void LoadImageBLL::removeLoad(LoadImageBllCallBack *callBack)
{
    _callBacksMutex.lock();
    _callBacks.removeAll(callBack);
    _callBacksMutex.unlock();
}



//LoadImageThread
LoadImageObj::LoadImageObj(QObject *parent, LoadImageBLL *manager)
    :QObject(parent)
{
    _manager = manager;

    _thread = new QThread(this);
    this->moveToThread(_thread);
    _thread->start();
}
LoadImageObj::~LoadImageObj()
{
    _thread->quit();
    _thread->wait();
}

bool LoadImageObj::event(QEvent * event)
{
//    EZDebug << event->type();
    bool returnCode = false;
    if(event->type()==QEvent::User+1){
        // this is load image event
        LoadImageBLLEvent *levent = (LoadImageBLLEvent*)event;
        QString path = levent->path();
        QPixmap pixmap(path);
        int error = 0;
        if(pixmap.isNull()){
            error = -1;
        }
//        QThread::currentThread()->sleep(2);
        LoadImageFinishEvent *fevent = new LoadImageFinishEvent((QEvent::Type)(QEvent::User+2));
        fevent->_path = levent->_path;
        fevent->_callBack = levent->_callBack;
        fevent->_error = error;
        fevent->_pixmap = pixmap;
//        EZDebug << error << pixmap.isNull();
        QApplication::postEvent(_manager,fevent);
        returnCode = true;
    }else{
       returnCode  = QObject::event(event);
    }
    return returnCode;
}


//LoadImageFinishEvent
LoadImageFinishEvent::LoadImageFinishEvent(QEvent::Type type):
    QEvent(type)
{
    _callBack = 0;
    _error = 0;
}
LoadImageFinishEvent::~LoadImageFinishEvent()
{
    _callBack = 0;
    _error = 0;
}

// LoadImageBLLEvent
LoadImageBLLEvent::LoadImageBLLEvent(QEvent::Type type):
    QEvent(type)
{
    _callBack = 0;
}
LoadImageBLLEvent::~LoadImageBLLEvent()
{
    _callBack = 0;
//    EZDebug << "~LoadImageBLLEvent";
}

QString LoadImageBLLEvent::path() const
{
    return _path;
}

void LoadImageBLLEvent::setPath(const QString &path)
{
    _path = path;
}
